package org.jeecg.modules.demo.workflow.instanceState;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.flowable.engine.TaskService;
import org.flowable.engine.task.Comment;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.bean.vo.WflowModelDetailVo;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.controller.ZyHazardInvestigationController;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.entity.ZyHazardInvestigation;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.entity.ZyRectificationInformation;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.entity.ZyReviewInformation;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.service.IZyHazardInvestigationService;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.service.IZyRectificationInformationService;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.service.IZyReviewInformationService;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.vo.ZyHazardInvestigationPage;
import org.jeecg.modules.demo.service.ModelGroupService;
import org.jeecg.modules.demo.utils.R;
import org.jeecg.modules.demo.workflow.bean.process.OrgUser;
import org.jeecg.modules.demo.workflow.bean.vo.ProcessStartParamsVo;
import org.jeecg.modules.demo.workflow.service.ProcessInstanceService;
import org.jeecg.modules.demo.workflow.service.ProcessTaskService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.ResolverStyle;
import java.time.format.SignStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 功能描述
 *
 * @program: jeecg-boot
 * @description:
 * @author: wwq
 * @create: 2024-04-21 16:31
 **/
@Slf4j
@Tag(name="隐患排查流程状态")
@RestController
@RequestMapping("wflow/ZyHazardInvestigationState")
public class ZyHazardInvestigationState {
    @Autowired
    private IZyHazardInvestigationService zyHazardInvestigationService;
    @Autowired
    private ProcessTaskService taskService;
    @Autowired
    private TaskService taskServiceFlowable;
    @Autowired
    private IZyRectificationInformationService zyRectificationInformationService;
    @Autowired
    private IZyReviewInformationService zyReviewInformationService;
    @Autowired
    private ModelGroupService modelGroupService;
    @Autowired
    private ISysDepartService sysDepartService;
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ProcessInstanceService processService;
    @Autowired
    private ZyHazardInvestigationController zyHazardInvestigationController;

    private ExecutorService executor = Executors.newFixedThreadPool(5); // 创建一个固定大小为5的线程池

    /**
     * 流程通过时监听器调用接口
     * 隐患排查-通过状态
     * @param instanceId 流程实例ID
     */
    @AutoLog(value = "隐患排查-通过状态")
    @Operation(summary = "隐患排查-通过状态", description = "隐患排查-通过状态")
    @PostMapping("setPassState")
    public Object setPassStatus(@RequestParam String instanceId) {
        System.out.println("instanceId = " + instanceId);
        String  mainDesc = "流程进行中";
        String rectifierDesc = "未整改";
        String reviewerDesc = "未复查";
        String result = "待整改";

        String s = "";
        String personName = "";
        String parentId = "";
        Map<String, Object> task = taskService.getTaskById(instanceId);
        System.out.println("task = " + task);
        // 使用线程池执行异步任务
        String finalParentId = parentId;
        executor.execute(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            List<Comment> processInstanceComments = taskServiceFlowable.getProcessInstanceComments(instanceId);
            String actComment = "";
            Date time = null;
            String text = "";
            String concatenatedUrls = null;
            System.out.println("processInstanceComments = " + processInstanceComments);
            if (!processInstanceComments.isEmpty()){
                for (Comment comment : processInstanceComments) {
                    System.out.println("acr1: " + comment.toString());
                    String id = (String) task.get("id");
                    if (id.equals(comment.getTaskId())) {
                        actComment = comment.getFullMessage();
                        time = comment.getTime();
                    }
                }

                System.out.println("act:" + actComment);
                // 解析 JSON 字符串
                JSONObject jsonObject = JSON.parseObject(actComment);

                // 获取 attachments 数组
                JSONArray attachments = jsonObject.getJSONArray("attachments");

                List<String> urlList = new ArrayList<>();
                // 提取两个 url
                for (int i = 0; i < attachments.size(); i++) {
                    JSONObject attachment = attachments.getJSONObject(i);
                    String url = attachment.getString("url");
                    System.out.println("URL " + (i + 1) + ": " + url);
                    urlList.add(url);
                }
                concatenatedUrls = String.join(",", urlList);
                System.out.println("Concatenated URLs: " + concatenatedUrls);

                // 获取 text 内容
                text = jsonObject.getString("text");
                System.out.println("Text: " + text);

            }else {
                text = "流程被拒绝";
                time= new Date();
            }
            String realname = (String) task.get("realname");
            String name1 = (String) task.get("name");




            ZyHazardInvestigation zyHazardInvestigation = zyHazardInvestigationService.getOne(new LambdaQueryWrapper<ZyHazardInvestigation>().
                    eq(ZyHazardInvestigation::getInstanceId, instanceId));
            if ("整改人".equals(name1)){
                System.out.println("finalParentId = " + zyHazardInvestigation.getId());
                zyRectificationInformationService.save(ZyRectificationInformation.builder().rectificationPersonnel(realname).completionTime(time)
                        .rectificationInfo(text).rectificationPhoto(concatenatedUrls).status("已整改").parentId(zyHazardInvestigation.getId()).build());
            }
            if ("复查人".equals(name1)) {
                System.out.println("finalParentId = " + zyHazardInvestigation.getId());
                zyReviewInformationService.save(ZyReviewInformation.builder().reviewPersonnel(realname).reviewTime(time)
                        .reviewDesc(text).reviewPhoto(concatenatedUrls).status("已复查").parentId(zyHazardInvestigation.getId()).build());
            }
        });

        if (task != null) {
            s = (String) task.get("taskDefinitionKey");
            System.out.println("s = " + s);
            personName = (String) task.get("name");
            if ("整改人".equals(personName)){
                rectifierDesc = "已整改";
                result = "待复查";
            }
            if ("复查人".equals(personName)) {
                mainDesc = "流程通过";
                rectifierDesc = "已整改";
                reviewerDesc = "已复查";
                result = "合格";
            }
            System.out.println("personName = " + personName);
        }

        ZyHazardInvestigation zyHazardInvestigation = zyHazardInvestigationService.getOne(new LambdaQueryWrapper<ZyHazardInvestigation>().
                eq(ZyHazardInvestigation::getInstanceId, instanceId));
        zyHazardInvestigation.setStatus(mainDesc);
        zyHazardInvestigation.setRectifierStatus(rectifierDesc);
        zyHazardInvestigation.setReviewerStatus(reviewerDesc);
        zyHazardInvestigation.setResult(result);
        zyHazardInvestigationService.updateById(zyHazardInvestigation);

        return R.ok(mainDesc);
    }



    /**
     * 流程通过时监听器调用接口
     * 隐患排查-驳回状态
     * @param instanceId 流程实例ID
     */
    @AutoLog(value = "隐患排查-驳回状态")
    @Operation(summary = "隐患排查-驳回状态", description = "隐患排查-驳回状态")
    @PostMapping("setRefuseState")
    public Object setRefuseStatus(@RequestParam String instanceId) {
        System.out.println("instanceId = " + instanceId);
        String  mainDesc = "审批被驳回";
        String rectifierDesc = "未整改";
        String reviewerDesc = "未复查";
        String result = "不合格";

        String s = "";
        String personName = "";
        String parentId = "";
        Map<String, Object> task = taskService.getTaskById(instanceId);
        System.out.println("task = " + task);
        // 使用线程池执行异步任务
        String finalParentId = parentId;
        executor.execute(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }


            List<Comment> processInstanceComments = taskServiceFlowable.getProcessInstanceComments(instanceId);
            String actComment = "";
            Date time = null;
            String text = "";
            String concatenatedUrls = null;
            System.out.println("processInstanceComments = " + processInstanceComments);
            if (!processInstanceComments.isEmpty()){
                for (Comment comment : processInstanceComments) {
                    System.out.println("acr1: " + comment.toString());
                    String id = (String) task.get("id");
                    if (id.equals(comment.getTaskId())) {
                        actComment = comment.getFullMessage();
                        time = comment.getTime();
                    }
                }

                System.out.println("act:" + actComment);
                // 解析 JSON 字符串
                JSONObject jsonObject = JSON.parseObject(actComment);

                // 获取 attachments 数组
                JSONArray attachments = jsonObject.getJSONArray("attachments");

                List<String> urlList = new ArrayList<>();
                // 提取两个 url
                for (int i = 0; i < attachments.size(); i++) {
                    JSONObject attachment = attachments.getJSONObject(i);
                    String url = attachment.getString("url");
                    System.out.println("URL " + (i + 1) + ": " + url);
                    urlList.add(url);
                }
                concatenatedUrls = String.join(",", urlList);
                System.out.println("Concatenated URLs: " + concatenatedUrls);

                // 获取 text 内容
                text = jsonObject.getString("text");
                System.out.println("Text: " + text);

            }else {
                text = "流程被拒绝";
                time= new Date();
            }
            String realname = (String) task.get("realname");
            String name1 = (String) task.get("name");


            ZyHazardInvestigation zyHazardInvestigation = zyHazardInvestigationService.getOne(new LambdaQueryWrapper<ZyHazardInvestigation>().
                    eq(ZyHazardInvestigation::getInstanceId, instanceId));
            if ("整改人".equals(name1)){
                System.out.println("finalParentId = " + zyHazardInvestigation.getId());
                zyRectificationInformationService.save(ZyRectificationInformation.builder().rectificationPersonnel(realname).completionTime(time)
                        .rectificationInfo(text).rectificationPhoto(concatenatedUrls).status("已整改").parentId(zyHazardInvestigation.getId()).build());
            }
            if ("复查人".equals(name1)) {
                System.out.println("finalParentId = " + zyHazardInvestigation.getId());
                zyReviewInformationService.save(ZyReviewInformation.builder().reviewPersonnel(realname).reviewTime(time)
                        .reviewDesc(text).reviewPhoto(concatenatedUrls).status("已复查").parentId(zyHazardInvestigation.getId()).build());
            }
        });

        if (task != null) {
            s = (String) task.get("taskDefinitionKey");
            System.out.println("s = " + s);
            personName = (String) task.get("name");
            if ("整改人".equals(personName)){
                rectifierDesc = "整改驳回";
                result = "不合格";
            }
            if ("复查人".equals(personName)) {
                reviewerDesc = "复查驳回";
                result = "不合格";
            }
            System.out.println("personName = " + personName);
        }

        ZyHazardInvestigation zyHazardInvestigation = zyHazardInvestigationService.getOne(new LambdaQueryWrapper<ZyHazardInvestigation>().
                eq(ZyHazardInvestigation::getInstanceId, instanceId));
        zyHazardInvestigation.setStatus(mainDesc);
        zyHazardInvestigation.setRectifierStatus(rectifierDesc);
        zyHazardInvestigation.setReviewerStatus(reviewerDesc);
        zyHazardInvestigation.setResult(result);
        zyHazardInvestigationService.updateById(zyHazardInvestigation);
        return R.ok(mainDesc);

    }

    /**
     * 流程通过时监听器调用接口
     * 隐患排查-撤销状态
     * @param instanceId 流程实例ID
     */
    @AutoLog(value = "隐患排查-撤销状态")
    @Operation(summary = "隐患排查-撤销状态", description = "隐患排查-撤销状态")
    @PostMapping("setCancelState")
    public Object setCancelStatus(@RequestParam String instanceId) {
        System.out.println("instanceId = " + instanceId);
        String  mainDesc = "审批被撤销";
        String rectifierDesc = "未整改";
        String reviewerDesc = "未复查";
        String result = "不合格";

        String s = "";
        String personName = "";
        String parentId = "";
        Map<String, Object> task = taskService.getTaskById(instanceId);
        System.out.println("task = " + task);
        // 使用线程池执行异步任务
        String finalParentId = parentId;
        executor.execute(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }


            List<Comment> processInstanceComments = taskServiceFlowable.getProcessInstanceComments(instanceId);
            String actComment = "";
            Date time = null;
            String text = "";
            String concatenatedUrls = null;
            System.out.println("processInstanceComments = " + processInstanceComments);
            if (!processInstanceComments.isEmpty()){
                for (Comment comment : processInstanceComments) {
                    System.out.println("acr1: " + comment.toString());
                    String id = (String) task.get("id");
                    if (id.equals(comment.getTaskId())) {
                        actComment = comment.getFullMessage();
                        time = comment.getTime();
                    }
                }

                System.out.println("act:" + actComment);
                // 解析 JSON 字符串
                JSONObject jsonObject = JSON.parseObject(actComment);

                // 获取 attachments 数组
                JSONArray attachments = jsonObject.getJSONArray("attachments");

                List<String> urlList = new ArrayList<>();
                // 提取两个 url
                for (int i = 0; i < attachments.size(); i++) {
                    JSONObject attachment = attachments.getJSONObject(i);
                    String url = attachment.getString("url");
                    System.out.println("URL " + (i + 1) + ": " + url);
                    urlList.add(url);
                }
                concatenatedUrls = String.join(",", urlList);
                System.out.println("Concatenated URLs: " + concatenatedUrls);

                // 获取 text 内容
                text = jsonObject.getString("text");
                System.out.println("Text: " + text);

            }else {
                text = "流程被撤销";
                time= new Date();
            }
            String realname = (String) task.get("realname");
            String name1 = (String) task.get("name");


            ZyHazardInvestigation zyHazardInvestigation = zyHazardInvestigationService.getOne(new LambdaQueryWrapper<ZyHazardInvestigation>().
                    eq(ZyHazardInvestigation::getInstanceId, instanceId));
            if ("整改人".equals(name1)){
                System.out.println("finalParentId = " + zyHazardInvestigation.getId());
                zyRectificationInformationService.save(ZyRectificationInformation.builder().rectificationPersonnel(realname).completionTime(time)
                        .rectificationInfo(text).rectificationPhoto(concatenatedUrls).status("已整改").parentId(zyHazardInvestigation.getId()).build());
            }
            if ("复查人".equals(name1)) {
                System.out.println("finalParentId = " + zyHazardInvestigation.getId());
                zyReviewInformationService.save(ZyReviewInformation.builder().reviewPersonnel(realname).reviewTime(time)
                        .reviewDesc(text).reviewPhoto(concatenatedUrls).status("已复查").parentId(zyHazardInvestigation.getId()).build());
            }
        });

        if (task != null) {
            s = (String) task.get("taskDefinitionKey");
            System.out.println("s = " + s);
            personName = (String) task.get("name");
            if ("整改人".equals(personName)){
                rectifierDesc = "整改撤销";
                result = "不合格";
            }
            if ("复查人".equals(personName)) {
                reviewerDesc = "复查撤销";
                result = "不合格";
            }
            System.out.println("personName = " + personName);
        }

        ZyHazardInvestigation zyHazardInvestigation = zyHazardInvestigationService.getOne(new LambdaQueryWrapper<ZyHazardInvestigation>().
                eq(ZyHazardInvestigation::getInstanceId, instanceId));
        zyHazardInvestigation.setStatus(mainDesc);
        zyHazardInvestigation.setRectifierStatus(rectifierDesc);
        zyHazardInvestigation.setReviewerStatus(reviewerDesc);
        zyHazardInvestigation.setResult(result);
        zyHazardInvestigationService.updateById(zyHazardInvestigation);
        return R.ok(mainDesc);

    }



//    @Operation(summary = "整改监督信息导入excel", description = "整改监督信息导入excel")
//    @PostMapping(value = "/importWflow")
//    public Result<ProcessStartParamsVo> addwflow(MultipartFile file, String formId,String pid) throws Exception {
//        List<ZyHazardInvestigationPage> wflowDtoList = new ArrayList<>();
//        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
////        System.out.println("loginUser = " + loginUser);
//        String realname = loginUser.getRealname();
//        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
//            Sheet sheet = workbook.getSheetAt(0);
//            for (int i = 3; i <= sheet.getLastRowNum(); i++) { // 跳过标题行
//                System.out.println("sheet.getLastRowNum() = " + sheet.getLastRowNum());
//                Row row = sheet.getRow(i);
//                // 跳过空行
//                if (row == null) {
//                    continue;
//                }
//                // 检查关键单元格是否为空（这里以第一列作为关键判断依据）
//                Cell firstCell = row.getCell(0);
//                if (firstCell == null || getCellValueAsString(firstCell).trim().isEmpty()) {
//                    continue; // 如果关键单元格为空，视为空行跳过
//                }
//                if (row != null) {
//                    // 1. 先创建基础DTO，设置公共属性
//                    ZyHazardInvestigationPage baseWflowDto = new ZyHazardInvestigationPage();
//                    baseWflowDto.setFlag(getCellValueAsString(row.getCell(0)));
//                    baseWflowDto.setIsComplete(getCellValueAsString(row.getCell(1)));
//                    baseWflowDto.setQualityType(getCellValueAsString(row.getCell(2)));
//                    baseWflowDto.setCommonProblem(getCellValueAsString(row.getCell(3)));
//                    baseWflowDto.setProblemDescription(getCellValueAsString(row.getCell(4)));
//                    baseWflowDto.setMeasure(getCellValueAsString(row.getCell(5)));
//                    baseWflowDto.setRectificationDeadline(getCellValueAsDate(row.getCell(6)));
//                    baseWflowDto.setProgress(getCellValueAsString(row.getCell(7)));
//                    baseWflowDto.setReviewerPerson(realname); // 复查人是公共属性
//                    // 2. 处理多部门（用逗号分隔）
//                    String transactorsDeptStr = getCellValueAsString(row.getCell(8));
//                    if (StringUtils.isNotBlank(transactorsDeptStr)) {
//                        // 拆分部门，处理可能的空格
//                        String[] deptArray = transactorsDeptStr.split(",");
//                        for (String dept : deptArray) {
//                            dept = dept.trim(); // 去除前后空格
//                            if (StringUtils.isBlank(dept)) {
//                                continue; // 跳过空部门
//                            }
//
//                            // 3. 为每个部门创建新的DTO，复制基础属性
//                            ZyHazardInvestigationPage wflowDto = new ZyHazardInvestigationPage();
//                            BeanUtils.copyProperties(baseWflowDto, wflowDto); // 复制公共属性
//
//                            // 4. 设置当前部门
//                            wflowDto.setDepartment(dept);
//
//                            // 5. 根据当前部门查询办理人
//                            LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
//                            queryWrapper.eq(SysDepart::getDepartName, dept);
//                            SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
//
//                            if (sysDepart != null) {
//                                LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
//                                userQuery.eq(SysUser::getDepartIds, sysDepart.getId());
//                                List<SysUser> sysUserList = sysUserService.list(userQuery);
//                                System.out.println("sysUserList = " + sysUserList);
//                                for (SysUser user : sysUserList) {
//                                    String roleId = sysUserRoleService.getRoleIdByUserId(user.getId());
//                                    if ("1939932967836213250".equals(roleId)) {
//                                        wflowDto.setRectifierPerson(user.getRealname());
//                                        break;
//                                    }
//                                }
//                            } else {
//                                // 部门不存在时的处理（可选）
//                                wflowDto.setRectifierPerson("未知整改人");
//                            }
//
//                            // 6. 添加到列表
//                            wflowDtoList.add(wflowDto);
//                            System.out.println("生成的wflowDto = " + wflowDto);
//                        }
//                    } else {
//                        // 没有部门时的处理（可选）
////                        baseWflowDto.setTransactorsDept("");
////                        baseWflowDto.setTransactors("");
//                        wflowDtoList.add(baseWflowDto);
//                    }
//                }
//            }
//        }
//
//        // 后续流程保持不变
//        WflowModelDetailVo model = (WflowModelDetailVo) modelGroupService.getModelById(formId);
//
//        // 创建线程池，核心线程数根据CPU核心数设定，这里使用CPU核心数 + 1
//        int corePoolSize = Runtime.getRuntime().availableProcessors() + 1;
//        ExecutorService executorService = new ThreadPoolExecutor(
//                corePoolSize,
//                corePoolSize * 2,
//                60L, TimeUnit.SECONDS,
//                new LinkedBlockingQueue<>(100),
//                new ThreadFactory() {
//                    private final AtomicInteger counter = new AtomicInteger(0);
//
//                    @Override
//                    public Thread newThread(Runnable r) {
//                        Thread thread = new Thread(r);
//                        thread.setName("import-wflow-thread-" + counter.incrementAndGet());
//                        thread.setDaemon(false); // 非守护线程
//                        return thread;
//                    }
//                },
//                new ThreadPoolExecutor.CallerRunsPolicy() // 当队列满时，让提交任务的线程执行任务，避免任务丢失
//        );
//
//        try {
//            // 存储所有异步任务，用于等待所有任务完成
//            List<CompletableFuture<Void>> futures = new ArrayList<>();
//           //在创建 CompletableFuture 之前获取请求上下文
//            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//            System.out.println("wflowDtoList = " + wflowDtoList);
//            for (ZyHazardInvestigationPage wflowDto : wflowDtoList) {
//                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
//                    try {
//                        // 在子线程开始时设置请求上下文
//                        RequestContextHolder.setRequestAttributes(attributes, true);
//
//                        ProcessStartParamsVo processStartParamsVo = new ProcessStartParamsVo();
//                        processStartParamsVo.setDeptId(loginUser.getDepartIds());
//                        Map<String, Object> formData = new HashMap<>();
//                        formData.put(model.getFormItems().get(0).getId(), wflowDto.getQualityType());
//                        formData.put(model.getFormItems().get(1).getId(), wflowDto.getFlag());
//                        formData.put(model.getFormItems().get(2).getId(), wflowDto.getIsComplete());
//                        formData.put(model.getFormItems().get(3).getId(), wflowDto.getCommonProblem());
//                        formData.put(model.getFormItems().get(4).getId(), wflowDto.getProblemDescription());
//                        formData.put(model.getFormItems().get(5).getId(), wflowDto.getMeasure());
//                        formData.put(model.getFormItems().get(6).getId(), wflowDto.getRectificationDeadline());
//                        formData.put(model.getFormItems().get(7).getId(), wflowDto.getProgress());
//                        System.out.println("formData = " + formData);
//                        processStartParamsVo.setFormData(formData);
//
//                        Map<String, List<OrgUser>> processUsers = new HashMap<>();
//                        List<OrgUser> usersForNode1 = new ArrayList<>();
//                        String id1 = sysUserService.getUserIdByRealName(wflowDto.getReviewerPerson());
//                        System.out.println("id1 = " + id1);
//                        List<OrgUser> usersForNode2 = new ArrayList<>();
//                        String id2 = sysUserService.getUserIdByRealName(wflowDto.getRectifierPerson());
//                        System.out.println("wflowDto.getRectifierPerson() = " + wflowDto.getRectifierPerson());
//                        System.out.println("id2 = " + id2);
//                        usersForNode1.add(new OrgUser(id1, wflowDto.getReviewerPerson(), "", "user", true));
//                        usersForNode2.add(new OrgUser(id2, wflowDto.getRectifierPerson(), "", "user", true));
//                        processUsers.put(model.getProcess().getChildren().getId(), usersForNode2);
//                        processUsers.put(model.getProcess().getChildren().getChildren().getId(), usersForNode1);
//                        processStartParamsVo.setProcessUsers(processUsers);
//                        System.out.println("processStartParamsVo = " + processStartParamsVo);
//                        String instanceId = processService.startProcess(model.getProcessDefId(), processStartParamsVo);
//                        wflowDto.setInstanceId(instanceId);
//                        wflowDto.setPid(pid);
//                        zyHazardInvestigationController.add(wflowDto);
//                    } catch (Exception e) {
//                        System.err.println("处理记录时发生错误: " + e.getMessage());
//                        throw new CompletionException(e);
//                    } finally {
//                        // 清理上下文避免内存泄漏
//                        RequestContextHolder.resetRequestAttributes();
//                    }
//                }, executorService);
//
//                futures.add(future);
//            }
//
//            // 等待所有任务完成
//            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//
//        } finally {
//            // 关闭线程池
//            executorService.shutdown();
//            // 等待线程池关闭
//            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
//                executorService.shutdownNow();
//            }
//        }
//
//        return Result.ok();
//    }

//
//    private String getCellValueAsString(Cell cell) {
//        if (cell == null) return "";
//        switch (cell.getCellType()) {
//            case STRING:
//                return cell.getStringCellValue();
//            case NUMERIC:
//                if (DateUtil.isCellDateFormatted(cell)) { // 判断是否是日期格式
//                    // 创建一个日期格式化对象
//                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                    // 返回格式化后的日期字符串
//                    return dateFormat.format(cell.getDateCellValue());
//                } else {
//                    // 非日期的数值直接返回其整数部分的字符串形式
//                    return String.valueOf((int) cell.getNumericCellValue());
//                }
//            default:
//                return "";
//        }
//    }
//    // 新增一个返回Date类型的方法
//    private Date getCellValueAsDate(Cell cell) {
//        if (cell == null) return null;
//        if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
//            return cell.getDateCellValue();
//        }
//        // 如果单元格不是日期格式但包含日期字符串，可以在这里添加解析逻辑
//        if (cell.getCellType() == CellType.STRING) {
//            try {
//                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//                return sdf.parse(cell.getStringCellValue());
//            } catch (ParseException e) {
//                // 可以根据实际格式调整或添加更多格式尝试
//                return null;
//            }
//        }
//        return null;
//    }



@Operation(summary = "整改监督信息导入excel", description = "整改监督信息导入excel")
@PostMapping(value = "/importWflow")
public Result<ProcessStartParamsVo> addwflow(MultipartFile file, String formId, String pid) throws Exception {
    List<ZyHazardInvestigationPage> wflowDtoList = new ArrayList<>();
    LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
    String realname = loginUser.getRealname();

    try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
        Sheet sheet = workbook.getSheetAt(0);

        // 获取所有合并区域信息
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();

        for (int i = 3; i <= sheet.getLastRowNum(); i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            // 检查关键单元格是否为空（考虑合并单元格）
            String firstCellValue = getMergedCellValue(sheet, mergedRegions, i, 0);
            if (firstCellValue == null || firstCellValue.trim().isEmpty()) {
                continue;
            }

            ZyHazardInvestigationPage baseWflowDto = new ZyHazardInvestigationPage();
            // 使用处理合并单元格的方法获取值
            baseWflowDto.setFlag(getMergedCellValue(sheet, mergedRegions, i, 0));
            baseWflowDto.setIsComplete(getMergedCellValue(sheet, mergedRegions, i, 1));
            baseWflowDto.setQualityType(getMergedCellValue(sheet, mergedRegions, i, 2));
            baseWflowDto.setCommonProblem(getMergedCellValue(sheet, mergedRegions, i, 3));
            baseWflowDto.setProblemDescription(getMergedCellValue(sheet, mergedRegions, i, 4));
            baseWflowDto.setMeasure(getMergedCellValue(sheet, mergedRegions, i, 5));

            // 处理日期类型的合并单元格
            Cell dateCell = getMergedCell(sheet, mergedRegions, i, 6);
//            baseWflowDto.setRectificationDeadline(dateCell != null ? getCellValueAsDateTime(dateCell) : null);
            baseWflowDto.setRectificationDeadline(parseDateCell(dateCell));
            baseWflowDto.setProgress(getMergedCellValue(sheet, mergedRegions, i, 7));
            baseWflowDto.setReviewerPerson(realname);

            // 处理多部门（用逗号分隔）
            String transactorsDeptStr = getMergedCellValue(sheet, mergedRegions, i, 8);
            if (StringUtils.isNotBlank(transactorsDeptStr)) {
                String[] deptArray = transactorsDeptStr.split(",");
                for (String dept : deptArray) {
                    dept = dept.trim();
                    if (StringUtils.isBlank(dept)) continue;

                    ZyHazardInvestigationPage wflowDto = new ZyHazardInvestigationPage();
                    BeanUtils.copyProperties(baseWflowDto, wflowDto);
                    wflowDto.setDepartment(dept);

                    // 查询办理人逻辑保持不变
                    LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(SysDepart::getDepartName, dept);
                    SysDepart sysDepart = sysDepartService.getOne(queryWrapper);

                    if (sysDepart != null) {
                        LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
                        userQuery.eq(SysUser::getDepartIds, sysDepart.getId());
                        List<SysUser> sysUserList = sysUserService.list(userQuery);

                        for (SysUser user : sysUserList) {
                            String roleId = sysUserRoleService.getRoleIdByUserId(user.getId());
                            if ("1939932967836213250".equals(roleId)) {
                                wflowDto.setRectifierPerson(user.getRealname());
                                break;
                            }
                        }
                    } else {
                        wflowDto.setRectifierPerson("未知整改人");
                    }

                    wflowDtoList.add(wflowDto);
                }
            } else {
                wflowDtoList.add(baseWflowDto);
            }
        }
    }

    // 后续线程池和流程处理逻辑保持不变
    WflowModelDetailVo model = (WflowModelDetailVo) modelGroupService.getModelById(formId);

    int corePoolSize = Runtime.getRuntime().availableProcessors() + 1;
    ExecutorService executorService = new ThreadPoolExecutor(
            corePoolSize,
            corePoolSize * 2,
            60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            new ThreadFactory() {
                private final AtomicInteger counter = new AtomicInteger(0);
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r);
                    thread.setName("import-wflow-thread-" + counter.incrementAndGet());
                    thread.setDaemon(false);
                    return thread;
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    try {
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        for (ZyHazardInvestigationPage wflowDto : wflowDtoList) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                try {
                    RequestContextHolder.setRequestAttributes(attributes, true);
                    ProcessStartParamsVo processStartParamsVo = new ProcessStartParamsVo();
                    if (wflowDto.getIsComplete().equals("已完成"))
                    {
                        wflowDto.setPid(pid);
                        zyHazardInvestigationController.add(wflowDto);
                        //结束本次循环
                        return;
                    }
                    processStartParamsVo.setDeptId(loginUser.getDepartIds());
                    Map<String, Object> formData = new HashMap<>();
                    String qualityType1 = wflowDto.getQualityType();
                    // 1. 创建一个 List，并将 qualityType1 放入其中
                    // Collections.singletonList() 是创建只包含一个元素的不可变列表的便捷方法
//                    List<String> qualityList = Collections.singletonList(qualityType1);
                    ArrayList<String> qualityList = new ArrayList<>();
                    qualityList.add(qualityType1);
//                    String result = String.format("[\"%s\"]", qualityType1);

                    formData.put(model.getFormItems().get(0).getId(), qualityList);
                    formData.put(model.getFormItems().get(1).getId(), wflowDto.getFlag());
                    formData.put(model.getFormItems().get(2).getId(), wflowDto.getIsComplete());
                    formData.put(model.getFormItems().get(3).getId(), wflowDto.getCommonProblem());
                    formData.put(model.getFormItems().get(4).getId(), wflowDto.getProblemDescription());
                    formData.put(model.getFormItems().get(5).getId(), wflowDto.getMeasure());

                    formData.put(model.getFormItems().get(6).getId(), wflowDto.getRectificationDeadline());
                    formData.put(model.getFormItems().get(7).getId(), wflowDto.getProgress());

                    processStartParamsVo.setFormData(formData);

                    Map<String, List<OrgUser>> processUsers = new HashMap<>();
                    List<OrgUser> usersForNode1 = new ArrayList<>();
                    String id1 = sysUserService.getUserIdByRealName(wflowDto.getReviewerPerson());
                    List<OrgUser> usersForNode2 = new ArrayList<>();
                    String id2 = sysUserService.getUserIdByRealName(wflowDto.getRectifierPerson());

                    usersForNode1.add(new OrgUser(id1, wflowDto.getReviewerPerson(), "", "user", true));
                    usersForNode2.add(new OrgUser(id2, wflowDto.getRectifierPerson(), "", "user", true));
                    processUsers.put(model.getProcess().getChildren().getId(), usersForNode2);
                    processUsers.put(model.getProcess().getChildren().getChildren().getId(), usersForNode1);
                    processStartParamsVo.setProcessUsers(processUsers);

                    String instanceId = processService.startProcess(model.getProcessDefId(), processStartParamsVo);
                    wflowDto.setInstanceId(instanceId);
                    wflowDto.setPid(pid);
                    zyHazardInvestigationController.add(wflowDto);
                } catch (Exception e) {
                    System.err.println("处理记录时发生错误: " + e.getMessage());
                    throw new CompletionException(e);
                } finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            }, executorService);

            futures.add(future);
        }

        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

    } finally {
        executorService.shutdown();
        if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
            executorService.shutdownNow();
        }
    }

    return Result.ok();
}

    /**
     * 获取合并单元格的值
     */
    private String getMergedCellValue(Sheet sheet, List<CellRangeAddress> mergedRegions, int row, int col) {
        Cell cell = getMergedCell(sheet, mergedRegions, row, col);
        return cell != null ? getCellValueAsString(cell) : null;
    }

    /**
     * 获取合并单元格对象（如果是合并单元格，返回合并区域的第一个单元格）
     */
    private Cell getMergedCell(Sheet sheet, List<CellRangeAddress> mergedRegions, int row, int col) {
        // 检查是否属于合并区域
        for (CellRangeAddress merged : mergedRegions) {
            if (merged.isInRange(row, col)) {
                // 返回合并区域的第一个单元格
                return sheet.getRow(merged.getFirstRow()).getCell(merged.getFirstColumn());
            }
        }
        // 不是合并单元格，直接返回当前单元格
        Row currentRow = sheet.getRow(row);
        return currentRow != null ? currentRow.getCell(col) : null;
    }

    /**
     * 将单元格内容转换为字符串
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    // 处理数字避免科学计数法
                    double value = cell.getNumericCellValue();
                    if (value == (long) value) {
                        return String.valueOf((long) value);
                    } else {
                        return String.valueOf(value);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return getCellValueAsString(new XSSFFormulaEvaluator((XSSFWorkbook) cell.getSheet().getWorkbook()).evaluateInCell(cell));
            default:
                return "";
        }
    }

//private Date parseDateCell(Cell cell) {
//    if (cell == null) {
//        System.err.println("解析日期失败：单元格为空");
//        return null;
//    }
//
//    try {
//        CellType cellType = cell.getCellType();
//        System.out.println("cellType = " + cellType);
//
//        if (cellType == NUMERIC) {
//            if (DateUtil.isCellDateFormatted(cell)) {
//                Date excelDate = cell.getDateCellValue();
//                System.out.printf("解析 Excel 内置日期成功：单元格内容（数字）-> 日期：%s%n", excelDate);
//                return excelDate;
//            }
//        } else if (cellType == STRING) {
//            String value = cell.getStringCellValue().trim();
//            if (value.isEmpty()) {
//                System.err.println("解析日期失败：字符串单元格内容为空");
//                return null;
//            }
//
//            if ("持续推进".equals(value)) {
//                LocalDateTime endOfYear = LocalDateTime.now()
//                        .plusYears(1)
//                        .withDayOfYear(1)
//                        .minusSeconds(1);
//                Date resultDate = Date.from(endOfYear.atZone(ZoneId.systemDefault()).toInstant());
//                System.out.printf("解析“持续推进”成功：默认日期 -> %s%n", resultDate);
//                return resultDate;
//            }
//
//            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
//                    .appendPattern("yyyy")
//                    .appendPattern("[/-]")
//                    .appendPattern("MM")
//                    .appendPattern("[/-]")
//                    .appendPattern("dd")
//                    .optionalStart()
//                    .appendLiteral(' ')
//                    .appendPattern("HH:mm:ss")
//                    .optionalEnd()
//                    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
//                    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
//                    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
//                    .toFormatter()
//                    .withResolverStyle(ResolverStyle.STRICT);
//
//            LocalDateTime parsedDateTime = LocalDateTime.parse(value, formatter);
//            Date resultDate = Date.from(parsedDateTime.atZone(ZoneId.systemDefault()).toInstant());
//            System.out.printf("解析字符串日期成功：%s -> %s%n", value, resultDate);
//            return resultDate;
//        }
//
//        System.err.printf("解析日期失败：不支持的单元格类型 -> %s%n", cellType);
//    } catch (Exception e) {
//        String cellContent = "";
//        try {
//            cellContent = cell.getStringCellValue();
//        } catch (Exception e1) {
//            // 若单元格不是字符串类型，忽略获取内容的异常
//        }
//        System.err.printf("解析日期失败：单元格内容='%s'，错误信息：%s%n", cellContent, e.getMessage());
//    }
//
//    return null;
//}
private Date parseDateCell(Cell cell) {
    if (cell == null) {
        System.err.println("解析日期失败：单元格为空");
        return null;
    }

    try {
        CellType cellType = cell.getCellType();
        System.out.println("cellType = " + cellType);

        // 1. 处理数字类型（可能是Excel原生日期，也可能是普通数字）
        if (cellType == CellType.NUMERIC) {
            // 尝试将其作为日期来解析
            // 即使格式是自定义的 "yyyy年m月d日"，cell.getDateCellValue() 也能正确获取日期
            Date excelDate = cell.getDateCellValue();

            // （可选但推荐）增加一个合理性检查，避免把普通数字（如123）解析成1900年的日期
            // Excel的日期起始于1900年，我们可以认为1970年之后的日期才是有效的业务日期
            if (excelDate.after(new Date(0))) { // new Date(0) 是 1970-01-01 00:00:00 UTC
                System.out.printf("解析 Excel 数字为日期成功（自定义格式）：单元格内容（数字）-> 日期：%s%n", excelDate);
                return excelDate;
            } else {
                // 如果日期太早，说明它可能不是一个有效的业务日期，而是一个普通数字
                System.err.println("解析日期失败：单元格是数字，但值太小，不被视为有效日期。");
                // 你可以在这里决定是返回null，还是抛出异常，或者将其作为数字处理
                return null;
            }
        }
        // 2. 处理字符串类型的日期
        else if (cellType == CellType.STRING) {
            String value = cell.getStringCellValue().trim();
            if (value.isEmpty()) {
                System.err.println("解析日期失败：字符串单元格内容为空");
                return null;
            }

//            if ("持续推进".equals(value)) {
//                LocalDateTime endOfYear = LocalDateTime.now()
//                        .plusYears(1)
//                        .withDayOfYear(1)
//                        .minusSeconds(1);
//                Date resultDate = Date.from(endOfYear.atZone(ZoneId.systemDefault()).toInstant());
//                System.out.printf("解析“持续推进”成功：默认日期 -> %s%n", resultDate);
//                return resultDate;
//            }
            if ("持续推进".equals(value)) {
                // 1. 获取当前日期和时间
                LocalDateTime now = LocalDateTime.now();

                // 2. 使用 TemporalAdjusters 将日期调整到今年的最后一天
                //    然后使用 withHour, withMinute, withSecond, withNano 将时间设置为 00:00:00
                LocalDateTime endOfYearStart = now.with(TemporalAdjusters.lastDayOfYear())
                        .withHour(0)
                        .withMinute(0)
                        .withSecond(0)
                        .withNano(0);

                // 或者使用更简洁的 atStartOfDay()
                // LocalDateTime endOfYearStart = now.with(TemporalAdjusters.lastDayOfYear()).toLocalDate().atStartOfDay();

                // 3. 转换为 Date 对象 (如果必须返回 Date)
                Date resultDate = Date.from(endOfYearStart.atZone(ZoneId.systemDefault()).toInstant());

                System.out.printf("解析“持续推进”成功：默认日期 -> %s%n", resultDate);
                return resultDate;
            }

//            // --- 重要修改：增加对 "yyyy年MM月dd日" 格式的支持 ---
//            // 定义一个包含多种可能格式的格式化器
//            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
//                    // 尝试解析 "yyyy年MM月dd日" 格式
//                    .appendOptional(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))
//                    // 尝试解析 "yyyy年M月d日" 格式 (月份和日期是一位数)
//                    .appendOptional(DateTimeFormatter.ofPattern("yyyy年M月d日"))
//                    // 尝试解析 "yyyy/MM/dd" 或 "yyyy-MM-dd" 格式
//                    .appendOptional(new DateTimeFormatterBuilder()
//                            .appendPattern("yyyy")
//                            .appendPattern("[/-]")
//                            .appendPattern("MM")
//                            .appendPattern("[/-]")
//                            .appendPattern("dd")
//                            .optionalStart()
//                            .appendLiteral(' ')
//                            .appendPattern("HH:mm:ss")
//                            .optionalEnd()
//                            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
//                            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
//                            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
//                            .toFormatter())
//                    .toFormatter(Locale.CHINA) // 使用中国Locale，确保对中文的正确处理
//                    .withResolverStyle(ResolverStyle.STRICT);
            // 定义一个包含多种可能格式的格式化器
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                    // 格式一：带年月日的中文格式 (月份和日期为1或2位数都可以)
                    .optionalStart()
                    .appendValue(ChronoField.YEAR, 4)
                    .appendLiteral('年')
                    .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NOT_NEGATIVE)
                    .appendLiteral('月')
                    .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NOT_NEGATIVE)
                    .appendLiteral('日')
                    .optionalEnd()
                    // 格式二：标准的 yyyy-MM-dd 或 yyyy/MM/dd 格式 (可带可选时间)
                    .optionalStart()
                    .appendPattern("yyyy")
                    .appendPattern("[/-]")
                    .appendPattern("MM")
                    .appendPattern("[/-]")
                    .appendPattern("dd")
                    .optionalStart()
                    .appendLiteral(' ')
                    .appendPattern("HH:mm:ss")
                    .optionalEnd()
                    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                    .optionalEnd()
                    .toFormatter(Locale.CHINA)
                    .withResolverStyle(ResolverStyle.STRICT);

            LocalDateTime parsedDateTime = LocalDateTime.parse(value, formatter);
            Date resultDate = Date.from(parsedDateTime.atZone(ZoneId.systemDefault()).toInstant());
            System.out.printf("解析字符串日期成功：%s -> %s%n", value, resultDate);
            return resultDate;
        }

        System.err.printf("解析日期失败：不支持的单元格类型 -> %s%n", cellType);
    } catch (Exception e) {
        String cellContent = "";
        try {
            // 如果是数字类型，获取其数字值作为内容
            if (cell.getCellType() == CellType.NUMERIC) {
                cellContent = String.valueOf(cell.getNumericCellValue());
            } else {
                cellContent = cell.getStringCellValue();
            }
        } catch (Exception e1) {
            // ignore
        }
        System.err.printf("解析日期失败：单元格内容='%s'，错误信息：%s%n", cellContent, e.getMessage());
    }

    return null;
}


}
